<template>
  <div class="robot-cluster-dashboard min-h-screen flex bg-gray-900 text-white" style="font-family: 'Inter', sans-serif; background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #334155 100%); min-height: 100vh; display: flex;">
    
    <!-- 侧边栏导航 -->
    <aside :class="sidebarCollapsed ? 'w-20' : 'w-72'" class="bg-gray-800/95 shadow-xl transition-all duration-200 ease-out border-r border-gray-700/50 flex flex-col" style="background: rgba(31, 41, 55, 0.95); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); border-right: 1px solid rgba(55, 65, 81, 0.5);">
      
      <!-- 侧边栏头部 -->
      <div :class="sidebarCollapsed ? 'p-2' : 'p-4'" class="border-b border-gray-700/50">
        <div :class="sidebarCollapsed ? 'flex items-center justify-center' : 'flex items-center space-x-3'">
          <div class="bg-gradient-to-r from-cyan-500 to-blue-600 text-white rounded-xl shadow-lg flex-shrink-0" :class="sidebarCollapsed ? 'p-2' : 'p-3'" style="background: linear-gradient(135deg, #06b6d4 0%, #2563eb 100%); color: white; border-radius: 12px; box-shadow: 0 10px 25px rgba(6, 182, 212, 0.3);">
            <i class="fa-solid fa-robot text-xl"></i>
          </div>
          <div v-show="!sidebarCollapsed" class="transition-opacity duration-300">
            <h1 class="text-lg font-bold bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent" style="font-weight: 700; background: linear-gradient(135deg, #22d3ee 0%, #60a5fa 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">机器人集群管控</h1>
            <p class="text-xs text-gray-400 flex items-center">
              <span class="w-2 h-2 bg-green-400 rounded-full mr-2 animate-pulse"></span>
              SLAM建图系统
            </p>
          </div>
        </div>
      </div>

      <!-- 导航菜单 -->
      <nav :class="sidebarCollapsed ? 'flex-1 p-2 space-y-2' : 'flex-1 p-4 space-y-2'">
        <div class="space-y-1">
          <!-- 首页 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'home'" 
              :class="[
                activeTab === 'home' ? 'bg-gradient-to-r from-cyan-500 to-blue-600 text-white shadow-lg' : 'text-gray-300 hover:text-cyan-400 hover:bg-gray-700/50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '首页' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-home text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">首页</span>
            </button>
            <!-- 悬停提示 -->
            <div v-if="sidebarCollapsed" class="absolute left-full ml-2 top-1/2 transform -translate-y-1/2 bg-gray-900 text-white px-3 py-2 rounded-lg text-sm opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
              首页
              <div class="absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900"></div>
            </div>
          </div>

          <!-- 地图管理 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'maps'" 
              :class="[
                activeTab === 'maps' ? 'bg-gradient-to-r from-cyan-500 to-blue-600 text-white shadow-lg' : 'text-gray-300 hover:text-cyan-400 hover:bg-gray-700/50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '地图管理' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-map text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">地图管理</span>
            </button>
            <!-- 悬停提示 -->
            <div v-if="sidebarCollapsed" class="absolute left-full ml-2 top-1/2 transform -translate-y-1/2 bg-gray-900 text-white px-3 py-2 rounded-lg text-sm opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
              地图管理
              <div class="absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900"></div>
            </div>
          </div>

          <!-- 巡检记录 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'patrol'" 
              :class="[
                activeTab === 'patrol' ? 'bg-gradient-to-r from-cyan-500 to-blue-600 text-white shadow-lg' : 'text-gray-300 hover:text-cyan-400 hover:bg-gray-700/50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '巡检记录' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-list text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">巡检记录</span>
            </button>
            <!-- 悬停提示 -->
            <div v-if="sidebarCollapsed" class="absolute left-full ml-2 top-1/2 transform -translate-y-1/2 bg-gray-900 text-white px-3 py-2 rounded-lg text-sm opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
              巡检记录
              <div class="absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900"></div>
            </div>
          </div>

          <!-- 车机系统 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'vehicle'" 
              :class="[
                activeTab === 'vehicle' ? 'bg-gradient-to-r from-cyan-500 to-blue-600 text-white shadow-lg' : 'text-gray-300 hover:text-cyan-400 hover:bg-gray-700/50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '车机系统' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-cog text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">车机系统</span>
            </button>
            <!-- 悬停提示 -->
            <div v-if="sidebarCollapsed" class="absolute left-full ml-2 top-1/2 transform -translate-y-1/2 bg-gray-900 text-white px-3 py-2 rounded-lg text-sm opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
              车机系统
              <div class="absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900"></div>
            </div>
          </div>

          <!-- 用户管理 -->
          <div class="relative group">
            <button 
              @click="activeTab = 'users'" 
              :class="[
                activeTab === 'users' ? 'bg-gradient-to-r from-cyan-500 to-blue-600 text-white shadow-lg' : 'text-gray-300 hover:text-cyan-400 hover:bg-gray-700/50',
                sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
              ]"
              :title="sidebarCollapsed ? '用户管理' : ''">
              <div class="flex-shrink-0">
                <i class="fa-solid fa-user text-lg"></i>
              </div>
              <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">用户管理</span>
            </button>
            <!-- 悬停提示 -->
            <div v-if="sidebarCollapsed" class="absolute left-full ml-2 top-1/2 transform -translate-y-1/2 bg-gray-900 text-white px-3 py-2 rounded-lg text-sm opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
              用户管理
              <div class="absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900"></div>
            </div>
          </div>
        </div>

        <!-- 分隔线 -->
        <div class="border-t border-gray-700/50 my-4"></div>

        <!-- 返回监控 -->
        <div class="relative group">
          <button 
            @click="goBack"
            :class="[
              'text-gray-400 hover:text-cyan-400 hover:bg-gray-700/50',
              sidebarCollapsed ? 'w-full flex items-center justify-center px-2 py-3 rounded-xl transition-colors duration-150' : 'w-full flex items-center space-x-3 px-4 py-3 rounded-xl transition-colors duration-150'
            ]"
            :title="sidebarCollapsed ? '返回监控' : ''">
            <div class="flex-shrink-0">
              <i class="fa-solid fa-arrow-left text-lg"></i>
            </div>
            <span v-show="!sidebarCollapsed" class="font-medium transition-opacity duration-300">返回监控</span>
          </button>
          <!-- 悬停提示 -->
          <div v-if="sidebarCollapsed" class="absolute left-full ml-2 top-1/2 transform -translate-y-1/2 bg-gray-900 text-white px-3 py-2 rounded-lg text-sm opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
            返回监控
            <div class="absolute right-full top-1/2 transform -translate-y-1/2 border-4 border-transparent border-r-gray-900"></div>
          </div>
        </div>

        <!-- 系统状态 -->
        <div v-show="!sidebarCollapsed" class="space-y-2">
          <h3 class="text-xs font-semibold text-gray-400 uppercase tracking-wider">系统状态</h3>
          <div class="space-y-1">
            <div class="flex items-center space-x-2 px-3 py-2 bg-green-900/30 rounded-lg border border-green-500/20">
              <div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
              <span class="text-xs text-green-400">SLAM在线</span>
            </div>
            <div class="flex items-center space-x-2 px-3 py-2 bg-cyan-900/30 rounded-lg border border-cyan-500/20">
              <div class="w-2 h-2 bg-cyan-400 rounded-full"></div>
              <span class="text-xs text-cyan-400">建图正常</span>
            </div>
          </div>
        </div>
      </nav>

      <!-- 侧边栏底部 - 用户信息区域 -->
      <div class="p-4 border-t border-gray-700/50">
        <div v-if="!sidebarCollapsed" class="flex items-center justify-between">
          <div class="flex items-center space-x-3">
            <div class="w-8 h-8 bg-gradient-to-r from-cyan-500 to-blue-600 rounded-full flex items-center justify-center">
              <i class="fa-solid fa-user text-white text-sm"></i>
            </div>
            <div>
              <p class="text-sm font-medium text-gray-200 truncate">{{ sysUser.username || '用户' }}</p>
              <p class="text-xs text-gray-400">晚上好: 用户</p>
            </div>
          </div>
          <button @click="logout" class="text-gray-400 hover:text-red-400 transition-colors" title="退出登录">
            <i class="fa-solid fa-sign-out-alt text-sm"></i>
          </button>
        </div>
        
        <!-- 收缩状态下的用户信息 -->
        <div v-else class="flex items-center justify-center">
          <button @click="logout" class="text-gray-400 hover:text-red-400 transition-colors" title="退出登录">
            <i class="fa-solid fa-sign-out-alt text-lg"></i>
          </button>
        </div>
      </div>
    </aside>

    <!-- 浮动收缩按钮 - 固定在页面左下角 -->
    <button 
      @click="toggleSidebar"
      class="fixed bottom-4 left-4 z-50 bg-cyan-500 hover:bg-cyan-600 text-white p-3 rounded-full shadow-lg transition-colors duration-200"
      :title="sidebarCollapsed ? '展开侧边栏' : '收缩侧边栏'">
      <i :class="sidebarCollapsed ? 'fa-solid fa-chevron-right' : 'fa-solid fa-chevron-left'" class="text-lg"></i>
    </button>

    <!-- 主内容区域 -->
    <div class="flex-1 flex flex-col min-h-screen">
      <!-- 顶部状态栏 -->
      <header class="bg-gray-800/95 shadow-lg border-b border-gray-700/50 flex-shrink-0" style="background: rgba(31, 41, 55, 0.95); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); border-bottom: 1px solid rgba(55, 65, 81, 0.5);">
        <div class="px-6 py-4">
          <div class="flex justify-between items-center">
            <div class="flex items-center space-x-4">
              <div class="text-sm text-gray-400">
                {{ currentTime }}
              </div>
              <div class="flex items-center space-x-2">
                <div class="w-8 h-8 bg-gradient-to-r from-red-500 to-pink-500 rounded-lg flex items-center justify-center">
                  <i class="fa-brands fa-bilibili text-white text-sm"></i>
                </div>
                <h1 class="text-2xl font-bold bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">浙高运机器人集群管控系统</h1>
              </div>
            </div>
            <div class="flex items-center space-x-4">
              <button class="text-gray-400 hover:text-white transition-colors">
                <i class="fa-solid fa-times mr-2"></i>Close Controls
              </button>
              <div class="flex items-center space-x-2 text-gray-300">
                <i class="fa-solid fa-user"></i>
                <span>晚上好: 用户</span>
                <i class="fa-solid fa-cog ml-2"></i>
              </div>
            </div>
          </div>
        </div>
      </header>

    <!-- 主内容区域 -->
    <main class="flex-1 overflow-y-auto p-4 bg-gray-900">
      <!-- 首页 -->
      <div v-if="activeTab === 'home'" class="grid grid-cols-12 gap-4 h-full">
        
        <!-- 中央：3D可视化区域（扩展至9列） -->
        <div class="col-span-9 bg-gray-800/80 rounded-lg border border-gray-700/50 relative">
          <div class="absolute top-4 left-4 text-white text-sm">
            <div class="bg-black/70 rounded px-2 py-1">00:14</div>
          </div>
          <div class="h-full flex items-center justify-center">
            <div class="text-center text-gray-400">
              <i class="fa-solid fa-cube text-6xl mb-4"></i>
              <p class="text-lg">3D点云可视化</p>
              <p class="text-sm">SLAM建图实时显示</p>
            </div>
          </div>
        </div>
        
        <!-- 右上角：视频流 -->
        <div class="col-span-3 space-y-4">
          <!-- 可见光视频 -->
          <div class="bg-gray-800/80 rounded-lg p-4 border border-gray-700/50">
            <h4 class="text-sm font-semibold text-white mb-2 flex items-center justify-between">
              <span>可见光</span>
              <span v-if="visibleLightStatus !== '已连接'" class="text-xs px-2 py-1 rounded" 
                    :class="visibleLightStatus === '连接中...' ? 'bg-yellow-500/20 text-yellow-400' : 
                            visibleLightStatus === '连接失败' ? 'bg-red-500/20 text-red-400' : 
                            'bg-gray-500/20 text-gray-400'">
                {{ visibleLightStatus }}
              </span>
            </h4>
            <div class="bg-gray-900 rounded h-32 relative overflow-hidden">
              <video 
                ref="visibleLightVideo"
                autoplay
                muted
                playsinline
                class="w-full h-full object-cover"
                @canplay="handleVisibleLightCanPlay"
                @error="handleVisibleLightError"
              ></video>
              <!-- 加载状态 -->
              <div v-if="visibleLightLoading" class="absolute inset-0 flex items-center justify-center bg-gray-900/80">
                <div class="text-center text-gray-400">
                  <i class="fa-solid fa-spinner fa-spin text-xl mb-1"></i>
                  <p class="text-xs">连接中...</p>
                </div>
              </div>
              <!-- 无视频状态 -->
              <div v-else-if="!visibleLightHasVideo" class="absolute inset-0 flex items-center justify-center">
                <div class="text-center text-gray-400">
                  <i class="fa-solid fa-video text-2xl mb-2"></i>
                  <p class="text-xs">视频流</p>
                </div>
              </div>
            </div>
            <div class="text-xs text-gray-400 mt-2">{{ currentVideoTime }}</div>
          </div>
          
          <!-- 深度相机 -->
          <div class="bg-gray-800/80 rounded-lg p-4 border border-gray-700/50">
            <h4 class="text-sm font-semibold text-white mb-2 flex items-center justify-between">
              <span>深度相机</span>
              <span v-if="depthCameraStatus !== '已连接'" class="text-xs px-2 py-1 rounded" 
                    :class="depthCameraStatus === '连接中...' ? 'bg-yellow-500/20 text-yellow-400' : 
                            depthCameraStatus === '连接失败' ? 'bg-red-500/20 text-red-400' : 
                            'bg-gray-500/20 text-gray-400'">
                {{ depthCameraStatus }}
              </span>
            </h4>
            <div class="bg-gray-900 rounded h-32 relative overflow-hidden">
              <video 
                ref="depthCameraVideo"
                autoplay
                muted
                playsinline
                class="w-full h-full object-cover"
                @canplay="handleDepthCameraCanPlay"
                @error="handleDepthCameraError"
              ></video>
              <!-- 加载状态 -->
              <div v-if="depthCameraLoading" class="absolute inset-0 flex items-center justify-center bg-gray-900/80">
                <div class="text-center text-gray-400">
                  <i class="fa-solid fa-spinner fa-spin text-xl mb-1"></i>
                  <p class="text-xs">连接中...</p>
                </div>
              </div>
              <!-- 无视频状态 -->
              <div v-else-if="!depthCameraHasVideo" class="absolute inset-0 flex items-center justify-center">
                <div class="text-center text-gray-400">
                  <i class="fa-solid fa-camera text-2xl mb-2"></i>
                  <p class="text-xs">深度流</p>
                </div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 删除了底部：巡检记录 面板 -->
        
        <!-- 底部：控制面板 -->
        <div class="col-span-9 grid grid-cols-2 gap-4">
          <!-- 车体控制 -->
          <div class="bg-gray-800/80 rounded-lg p-4 border border-gray-700/50">
            <h4 class="text-sm font-semibold text-white mb-4">车体控制</h4>
            <div class="space-y-4">
              <!-- 方向控制 -->
              <div class="flex justify-center">
                <div class="grid grid-cols-3 gap-1">
                  <div></div>
                  <button 
                    @mousedown="handleCarControl('forward')" 
                    @mouseup="handleCarControl('stop')"
                    @touchstart="handleCarControl('forward')"
                    @touchend="handleCarControl('stop')"
                    class="w-8 h-8 bg-gray-700 hover:bg-cyan-600 active:bg-cyan-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-up text-white text-sm"></i>
                  </button>
                  <div></div>
                  <button 
                    @mousedown="handleCarControl('left')" 
                    @mouseup="handleCarControl('stop')"
                    @touchstart="handleCarControl('left')"
                    @touchend="handleCarControl('stop')"
                    class="w-8 h-8 bg-gray-700 hover:bg-cyan-600 active:bg-cyan-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-left text-white text-sm"></i>
                  </button>
                  <button 
                    @click="handleCarControl('stop')"
                    class="w-8 h-8 bg-gray-700 hover:bg-red-600 active:bg-red-500 rounded flex items-center justify-center transition-colors">
                    <span class="text-white text-xs">空档</span>
                  </button>
                  <button 
                    @mousedown="handleCarControl('right')" 
                    @mouseup="handleCarControl('stop')"
                    @touchstart="handleCarControl('right')"
                    @touchend="handleCarControl('stop')"
                    class="w-8 h-8 bg-gray-700 hover:bg-cyan-600 active:bg-cyan-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-right text-white text-sm"></i>
                  </button>
                  <div></div>
                  <button 
                    @mousedown="handleCarControl('backward')" 
                    @mouseup="handleCarControl('stop')"
                    @touchstart="handleCarControl('backward')"
                    @touchend="handleCarControl('stop')"
                    class="w-8 h-8 bg-gray-700 hover:bg-cyan-600 active:bg-cyan-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-down text-white text-sm"></i>
                  </button>
                  <div></div>
                </div>
              </div>
              
              <!-- 速度控制 -->
              <div class="flex justify-center space-x-2">
                <button 
                  @click="handleSpeedControl('increase')"
                  class="px-3 py-1 bg-gray-700 hover:bg-green-600 rounded text-white text-xs transition-colors">
                  加速
                </button>
                <button 
                  @click="handleSpeedControl('decrease')"
                  class="px-3 py-1 bg-gray-700 hover:bg-yellow-600 rounded text-white text-xs transition-colors">
                  减速
                </button>
              </div>
              
              <!-- 当前速度显示 -->
              <div class="text-center text-xs text-gray-400">
                当前速度: {{ carSpeed }}%
              </div>
            </div>
          </div>
          
          <!-- 云台控制 -->
          <div class="bg-gray-800/80 rounded-lg p-4 border border-gray-700/50">
            <h4 class="text-sm font-semibold text-white mb-4">云台控制</h4>
            <div class="space-y-4">
              <!-- 方向控制 -->
              <div class="flex justify-center">
                <div class="grid grid-cols-3 gap-1">
                  <div></div>
                  <button 
                    @mousedown="handleGimbalControl('up')" 
                    @mouseup="handleGimbalControl('center')"
                    @touchstart="handleGimbalControl('up')"
                    @touchend="handleGimbalControl('center')"
                    class="w-8 h-8 bg-gray-700 hover:bg-purple-600 active:bg-purple-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-up text-white text-sm"></i>
                  </button>
                  <div></div>
                  <button 
                    @mousedown="handleGimbalControl('left')" 
                    @mouseup="handleGimbalControl('center')"
                    @touchstart="handleGimbalControl('left')"
                    @touchend="handleGimbalControl('center')"
                    class="w-8 h-8 bg-gray-700 hover:bg-purple-600 active:bg-purple-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-left text-white text-sm"></i>
                  </button>
                  <button 
                    @click="handleGimbalControl('center')"
                    class="w-8 h-8 bg-gray-700 hover:bg-purple-600 active:bg-purple-500 rounded flex items-center justify-center transition-colors">
                    <span class="text-white text-xs">中心</span>
                  </button>
                  <button 
                    @mousedown="handleGimbalControl('right')" 
                    @mouseup="handleGimbalControl('center')"
                    @touchstart="handleGimbalControl('right')"
                    @touchend="handleGimbalControl('center')"
                    class="w-8 h-8 bg-gray-700 hover:bg-purple-600 active:bg-purple-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-right text-white text-sm"></i>
                  </button>
                  <div></div>
                  <button 
                    @mousedown="handleGimbalControl('down')" 
                    @mouseup="handleGimbalControl('center')"
                    @touchstart="handleGimbalControl('down')"
                    @touchend="handleGimbalControl('center')"
                    class="w-8 h-8 bg-gray-700 hover:bg-purple-600 active:bg-purple-500 rounded flex items-center justify-center transition-colors">
                    <i class="fa-solid fa-arrow-down text-white text-sm"></i>
                  </button>
                  <div></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 地图管理 -->
      <div v-if="activeTab === 'maps'" class="space-y-6">
        <div class="bg-gray-800/80 rounded-lg p-6 border border-gray-700">
          <h2 class="text-xl font-semibold mb-4">地图管理</h2>
          <p class="text-gray-300 text-sm">这里展示地图列表和相关操作（占位）。</p>
        </div>
      </div>

      <!-- 会话管理 -->
      <div v-if="activeTab === 'sessions'" class="space-y-6">
        <div class="bg-gray-800/80 rounded-lg p-6 border border-gray-700">
          <h2 class="text-xl font-semibold mb-4">会话管理</h2>
          <p class="text-gray-300 text-sm">这里展示会话列表与启动/暂停/停止（占位）。</p>
        </div>
      </div>

      <!-- 实时建模 -->
      <div v-if="activeTab === 'realtime'" class="space-y-4">
        <!-- 顶部子视图切换 -->
        <div class="bg-gray-800/80 rounded-lg p-4 border border-gray-700/50 flex items-center gap-2">
          <button
            @click="realtimeViewMode = 'webrtc'"
            :class="realtimeViewMode === 'webrtc' ? 'bg-cyan-600 text-white' : 'bg-gray-700 text-gray-200 hover:bg-gray-600'"
            class="px-3 py-2 rounded"
          >
            WebRTC
          </button>
          <button
            @click="realtimeViewMode = 'video'"
            :class="realtimeViewMode === 'video' ? 'bg-cyan-600 text-white' : 'bg-gray-700 text-gray-200 hover:bg-gray-600'"
            class="px-3 py-2 rounded"
          >
            视频
          </button>
          <button
            @click="realtimeViewMode = '3d'"
            :class="realtimeViewMode === '3d' ? 'bg-cyan-600 text-white' : 'bg-gray-700 text-gray-200 hover:bg-gray-600'"
            class="px-3 py-2 rounded"
          >
            3D
          </button>
          <div class="ml-auto text-sm text-gray-300">
            当前会话ID: <span class="text-cyan-400">{{ (selectedSession && selectedSession.id) || '未选择' }}</span>
          </div>
        </div>

        <!-- 子视图容器 -->
        <div v-if="realtimeViewMode === 'webrtc'">
          <SlamRealtimeView :session-id="(selectedSession && selectedSession.id) || 1" />
        </div>
        <div v-else-if="realtimeViewMode === 'video'">
          <WebRTCStreamView />
        </div>
        <div v-else-if="realtimeViewMode === '3d'">
          <SlamVisualization3D />
        </div>
      </div>

      <!-- 巡检记录 -->
      <div v-if="activeTab === 'patrol'" class="space-y-6">
        <div class="bg-gray-800/80 rounded-lg p-6 border border-gray-700">
          <h2 class="text-xl font-semibold mb-4">巡检记录</h2>
          <p class="text-gray-300 text-sm">这里展示巡检记录列表（占位）。</p>
        </div>
      </div>

      <!-- 车机系统 -->
      <div v-if="activeTab === 'vehicle'" class="space-y-6">
        <div class="bg-gray-800/80 rounded-lg p-6 border border-gray-700">
          <h2 class="text-xl font-semibold mb-4">车机系统</h2>
          <p class="text-gray-300 text-sm">这里展示车机系统配置与控制（占位）。</p>
        </div>
      </div>

      <!-- 用户管理 -->
      <div v-if="activeTab === 'users'" class="space-y-6">
        <div class="bg-gray-800/80 rounded-lg p-6 border border-gray-700">
          <h2 class="text-xl font-semibold mb-4">用户管理</h2>
          <p class="text-gray-300 text-sm">这里展示用户列表与权限配置（占位）。</p>
        </div>
      </div>
    </main>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, reactive } from 'vue'
import { useRouter } from 'vue-router'
import axios from 'axios'
import SlamRealtimeView from './SlamRealtimeView.vue'
import Slam3DVisualization from './Slam3DVisualization.vue'
import WebRTCStreamView from './WebRTCStreamView.vue'
import SlamVisualization3D from './SlamVisualization3D.vue'
import { slamSessionApi, slamDataUtils } from '../services/slamApi.js'
import { defineUser } from '../store/userStore.js'
import config, { buildUrls } from '../config/index.js'
import { safePlayVideo } from '../utils/videoPlayManager.js'
import getCarControlClient, { generateServoCommand } from '../utils/carControl.js'

const router = useRouter()

// 用户状态管理
const sysUser = defineUser()

// 响应式数据
const activeTab = ref('home')
const sidebarCollapsed = ref(false)
const statistics = ref(null)
const maps = ref([])
const mapsLoading = ref(false)
const sessions = ref([])
const sessionsLoading = ref(false)
const createMapLoading = ref(false)
const createSessionLoading = ref(false)
const selectedSession = ref(null)
const realtimeViewMode = ref('3d') // 默认显示3D可视化
const currentTime = ref('')
const currentVideoTime = ref('')

// 可见光视频相关
const visibleLightVideo = ref(null)
const visibleLightStatus = ref('等待连接')
const visibleLightLoading = ref(false)
const visibleLightHasVideo = ref(false)
const visibleLightConnection = ref(null)

// 深度相机视频相关
const depthCameraVideo = ref(null)
const depthCameraStatus = ref('等待连接')
const depthCameraLoading = ref(false)
const depthCameraHasVideo = ref(false)
const depthCameraConnection = ref(null)

// 小车控制相关
const carControlClient = getCarControlClient()
const carSpeed = ref(50) // 默认速度50%
const carControlConnected = ref(false)

// 云台控制相关
// 云台舵机索引映射：0-水平，1-垂直
const gimbalServoIndex = {
  horizontal: 0,  // 水平方向
  vertical: 1    // 垂直方向
}



// 表单数据
const newMap = reactive({
  mapName: '',
  description: ''
})

const newSession = reactive({
  sessionName: '',
  mapId: '',
  videoSource: 'webrtc://8.136.52.147:8080/live/livestream'
})

// 方法
const goBack = () => {
  router.push('/showSchedule')
}

const logout = () => {
  sysUser.uid = ''
  sysUser.username = ''
  router.push('/login')
}

const toggleSidebar = () => {
  sidebarCollapsed.value = !sidebarCollapsed.value
}

const refreshData = () => {
  loadStatistics()
  if (activeTab.value === 'maps') {
    loadMaps()
  } else if (activeTab.value === 'sessions') {
    loadSessions()
  }
}


const loadStatistics = async () => {
  try {
    // 并行获取地图和会话统计信息
    const [mapsResponse, sessionsResult] = await Promise.all([
      fetch('/api/slam/maps'),
      slamSessionApi.getSessions()
    ])
    
    let totalMaps = 0
    let mapStatusCounts = {
      COMPLETED: 0,
      BUILDING: 0,
      FAILED: 0,
      PAUSED: 0
    }
    
    // 处理地图数据
    if (mapsResponse.ok) {
      const mapsResult = await mapsResponse.json()
      if (mapsResult.code === 200) {
        const maps = mapsResult.data.maps || []
        totalMaps = maps.length
        mapStatusCounts = maps.reduce((counts, map) => {
          counts[map.status] = (counts[map.status] || 0) + 1
          return counts
        }, { COMPLETED: 0, BUILDING: 0, FAILED: 0, PAUSED: 0 })
        console.log('✅ 加载地图统计成功:', { totalMaps, mapStatusCounts })
      }
    }
    
    // 处理会话数据
    let totalSessions = 0
    let activeSessions = 0
    
    // 处理Spring Boot后端格式 {success: true, data: {code: 200, data: {sessions: [...]}}}
    if (sessionsResult.success && sessionsResult.data.code === 200) {
      const sessions = sessionsResult.data.data.sessions
      totalSessions = sessions.length
      activeSessions = sessions.filter(s => s.status === 'RUNNING').length
    }
    // 处理Python SLAM服务格式 {success: true, data: {data: {success: true, sessions: [...]}}}
    else if (sessionsResult.success && sessionsResult.data.data?.success) {
      const sessions = sessionsResult.data.data.sessions || []
      totalSessions = sessions.length
      activeSessions = sessions.filter(s => s.status === 'RUNNING').length
    }
    
    // 更新统计信息
    statistics.value = {
      totalMaps,
      totalSessions,
      activeSessions,
      mapStatusCounts
    }
    
    console.log('✅ 统计信息更新完成:', statistics.value)
    
  } catch (error) {
    console.error('加载统计信息失败:', error)
  }
}

const loadMaps = async () => {
  mapsLoading.value = true
  try {
    // 调用后端SLAM地图API
    const response = await fetch('/api/slam/maps')
    if (response.ok) {
      const result = await response.json()
      if (result.code === 200) {
        maps.value = result.data.maps || []
        console.log('✅ 加载地图列表成功:', maps.value)
      } else {
        console.error('加载地图列表失败:', result.message)
        maps.value = []
      }
    } else {
      console.error('加载地图列表失败: HTTP', response.status)
      maps.value = []
    }
  } catch (error) {
    console.error('加载地图列表失败:', error)
    maps.value = []
  } finally {
    mapsLoading.value = false
  }
}

const loadSessions = async () => {
  console.log('🚀 开始加载会话列表...')
  sessionsLoading.value = true
  try {
    console.log('📡 调用slamSessionApi.getSessions()...')
    const result = await slamSessionApi.getSessions()
    console.log('🔍 会话API响应:', result)
    console.log('🔍 result.success:', result.success)
    console.log('🔍 result.data:', result.data)
    console.log('🔍 result.data类型:', typeof result.data)
    console.log('🔍 result.data.success:', result.data?.success)
    console.log('🔍 result.data.sessions:', result.data?.sessions)
    
    // 处理Python SLAM服务的响应格式
    // 实际响应: {success: true, data: {data: {sessions: [...], success: true, total: 1}}}
    if (result.success && result.data) {
      console.log('✅ API调用成功，开始处理数据...')
      console.log('🔍 原始数据:', result.data)
      console.log('🔍 嵌套数据:', result.data.data)
      console.log('🔍 sessions数组:', result.data.data?.sessions)
      
      // 转换数据格式以适配现有界面
      const content = result.data.data?.sessions || []
      console.log('🔍 处理后的content:', content)
      console.log('🔍 content类型:', typeof content)
      console.log('🔍 content是否为数组:', Array.isArray(content))
      console.log('🔍 content长度:', content.length)
      
      try {
        sessions.value = content.map(session => {
          console.log('🔍 处理会话:', session)
          return {
            id: session.id,
            sessionName: session.sessionName,
            status: session.status,
            framesReceived: session.currentFrame || 0,
            framesProcessed: session.currentFrame || 0,
            slamStarted: session.status === 'RUNNING',
            createdAt: session.createdAt || new Date().toISOString(),
            lastActivity: session.startedAt || session.createdAt || new Date().toISOString(),
            mapId: session.mapId || null,
            videoSource: session.videoSource || 'webrtc://8.136.52.147/live/livestream'
          }
        })
        
        console.log('✅ 加载会话列表成功:', sessions.value.length, '个会话')
        console.log('📋 会话列表:', sessions.value.map(s => s.sessionName))
        console.log('🔍 当前selectedSession:', selectedSession.value)
        console.log('🔍 当前realtimeViewMode:', realtimeViewMode.value)
        console.log('🔍 sessions数组内容:', sessions.value)
        console.log('🔍 sessions.length:', sessions.value.length)
      } catch (error) {
        console.error('❌ 映射会话数据时出错:', error)
        sessions.value = []
      }
      
      // 自动选择第一个会话，方便用户直接看到3D可视化
      if (sessions.value.length > 0 && !selectedSession.value) {
        selectedSession.value = sessions.value[0]
        console.log('🎯 自动选择第一个会话:', selectedSession.value.sessionName)
      }
    } else {
      console.error('❌ 加载会话列表失败:', result.data?.message || result.error)
      console.error('❌ 响应格式:', result)
    }
  } catch (error) {
    console.error('❌ 加载会话列表异常:', error)
    console.error('❌ 错误堆栈:', error.stack)
  } finally {
    sessionsLoading.value = false
    console.log('🏁 会话加载完成')
  }
}

const createMap = async () => {
  createMapLoading.value = true
  try {
    // 暂时禁用地图功能，因为新的会话管理系统还没有实现地图管理
    alert('地图功能暂时不可用，请使用会话管理功能')
    console.log('地图功能暂时不可用，请使用会话管理功能')
  } catch (error) {
    console.error('创建地图失败:', error)
    alert('创建地图失败: ' + error.message)
  } finally {
    createMapLoading.value = false
  }
}

const createSession = async () => {
  createSessionLoading.value = true
  try {
    const result = await slamSessionApi.createSession(newSession.sessionName || null)
    if (result.success && result.data.success) {
      alert('会话创建成功')
      newSession.sessionName = ''
      newSession.mapId = ''
      newSession.videoSource = 'webrtc://8.136.52.147:8080/live/livestream'
      loadSessions()
    } else {
      alert('会话创建失败: ' + (result.data?.message || result.error))
    }
  } catch (error) {
    console.error('创建会话失败:', error)
    alert('创建会话失败: ' + error.message)
  } finally {
    createSessionLoading.value = false
  }
}

const uploadVideo = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'video/*'
  input.onchange = async (e) => {
    const file = e.target.files[0]
    if (file) {
      const formData = new FormData()
      formData.append('file', file)
      
      try {
        const response = await axios.post('/api/slam/upload/video', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
        if (response.data.code === 200) {
          newSession.videoSource = response.data.data.filePath
          alert('视频上传成功')
        } else {
          alert('视频上传失败: ' + response.data.message)
        }
      } catch (error) {
        console.error('上传视频失败:', error)
        alert('上传视频失败: ' + error.message)
      }
    }
  }
  input.click()
}

const startSession = async (sessionId) => {
  try {
    const result = await slamSessionApi.startSlam(sessionId)
    if (result.success && result.data.success) {
      alert('会话启动成功')
      loadSessions()
    } else {
      alert('会话启动失败: ' + (result.data?.message || result.error))
    }
  } catch (error) {
    console.error('启动会话失败:', error)
    alert('启动会话失败: ' + error.message)
  }
}

const pauseSession = async (sessionId) => {
  try {
    const response = await axios.post(`/api/slam/sessions/${sessionId}/pause`)
    if (response.data.code === 200) {
      alert('会话暂停成功')
      loadSessions()
    } else {
      alert('会话暂停失败: ' + response.data.message)
    }
  } catch (error) {
    console.error('暂停会话失败:', error)
    alert('暂停会话失败: ' + error.message)
  }
}

const resumeSession = async (sessionId) => {
  try {
    const response = await axios.post(`/api/slam/sessions/${sessionId}/resume`)
    if (response.data.code === 200) {
      alert('会话恢复成功')
      loadSessions()
    } else {
      alert('会话恢复失败: ' + response.data.message)
    }
  } catch (error) {
    console.error('恢复会话失败:', error)
    alert('恢复会话失败: ' + error.message)
  }
}

const stopSession = async (sessionId) => {
  try {
    const result = await slamSessionApi.stopSlam(sessionId)
    if (result.success && result.data.success) {
      alert('会话停止成功')
      loadSessions()
    } else {
      alert('会话停止失败: ' + (result.data?.message || result.error))
    }
  } catch (error) {
    console.error('停止会话失败:', error)
    alert('停止会话失败: ' + error.message)
  }
}

const deleteMap = async (mapId) => {
  if (confirm('确定要删除这个地图吗？')) {
    try {
      // 暂时禁用地图功能，因为新的会话管理系统还没有实现地图管理
      alert('地图功能暂时不可用，请使用会话管理功能')
      console.log('地图功能暂时不可用，请使用会话管理功能')
    } catch (error) {
      console.error('删除地图失败:', error)
      alert('删除地图失败: ' + error.message)
    }
  }
}

const viewMapDetails = (map) => {
  alert(`地图详情:\n名称: ${map.mapName}\n描述: ${map.description || '无'}\n状态: ${getStatusText(map.status)}\n关键帧: ${map.keyframeCount || 0}\n地图点: ${map.mappointCount || 0}`)
}

const viewSessionDetails = (session) => {
  alert(`会话详情:\n名称: ${session.sessionName}\n状态: ${getSessionStatusText(session.status)}\n视频源: ${session.videoSource}\n进度: ${(session.progressPercentage || 0).toFixed(1)}%`)
}

const getStatusColor = (status) => {
  const colors = {
    'BUILDING': 'bg-yellow-100 text-yellow-800',
    'COMPLETED': 'bg-green-100 text-green-800',
    'FAILED': 'bg-red-100 text-red-800',
    'PAUSED': 'bg-blue-100 text-blue-800'
  }
  return colors[status] || 'bg-gray-100 text-gray-800'
}

const getStatusText = (status) => {
  const texts = {
    'BUILDING': '建图中',
    'COMPLETED': '已完成',
    'FAILED': '失败',
    'PAUSED': '暂停'
  }
  return texts[status] || status
}

const getSessionStatusColor = (status) => {
  const colors = {
    'STARTING': 'bg-blue-100 text-blue-800',
    'RUNNING': 'bg-green-100 text-green-800',
    'PAUSED': 'bg-yellow-100 text-yellow-800',
    'STOPPED': 'bg-gray-100 text-gray-800',
    'ERROR': 'bg-red-100 text-red-800'
  }
  return colors[status] || 'bg-gray-100 text-gray-800'
}

const getSessionStatusText = (status) => {
  const texts = {
    'STARTING': '启动中',
    'RUNNING': '运行中',
    'PAUSED': '暂停',
    'STOPPED': '已停止',
    'ERROR': '错误'
  }
  return texts[status] || status
}

const selectSession = (session) => {
  selectedSession.value = session
  console.log('🎯 选择会话:', session.sessionName, 'ID:', session.id)
  // 自动切换到实时建模标签页和3D可视化模式
  activeTab.value = 'realtime'
  realtimeViewMode.value = '3d'
}

const formatDate = (dateString) => {
  if (!dateString) return '未知'
  const date = new Date(dateString)
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const formatTime = (timeString) => {
  if (!timeString) return '未知'
  const date = new Date(timeString)
  return date.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}




// 更新时间
const updateTime = () => {
  const now = new Date()
  currentTime.value = now.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
  currentVideoTime.value = now.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 连接可见光视频流
const connectVisibleLightVideo = async () => {
  if (!visibleLightVideo.value) return
  
  try {
    visibleLightLoading.value = true
    visibleLightStatus.value = '连接中...'
    
    const video = visibleLightVideo.value
    const pc = new RTCPeerConnection({
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' }
      ]
    })
    
    pc.addTransceiver('video', { direction: 'recvonly' })
    pc.addTransceiver('audio', { direction: 'recvonly' })
    
    visibleLightConnection.value = pc
    
    pc.ontrack = async (event) => {
      console.log('✅ 可见光视频流已接收')
      video.srcObject = event.streams[0]
      await safePlayVideo(video, { muted: true })
      visibleLightHasVideo.value = true
      visibleLightStatus.value = '已连接'
      visibleLightLoading.value = false
    }
    
    pc.oniceconnectionstatechange = () => {
      if (pc.iceConnectionState === 'connected') {
        visibleLightStatus.value = '已连接'
        visibleLightLoading.value = false
      } else if (pc.iceConnectionState === 'failed') {
        visibleLightStatus.value = '连接失败'
        visibleLightLoading.value = false
      }
    }
    
    const offer = await pc.createOffer()
    await pc.setLocalDescription(offer)
    
    const response = await fetch(buildUrls.srsApi('/rtc/v1/play/'), {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        api: buildUrls.srsApi('/rtc/v1/play/'),
        streamurl: buildUrls.webrtc(),
        sdp: offer.sdp
      })
    })
    
    if (response.ok) {
      const data = await response.json()
      if (data.code === 0) {
        await pc.setRemoteDescription(new RTCSessionDescription({
          type: 'answer',
          sdp: data.sdp
        }))
      } else {
        throw new Error(data.message || '连接失败')
      }
    } else {
      throw new Error('HTTP错误: ' + response.status)
    }
  } catch (error) {
    console.error('可见光视频连接失败:', error)
    visibleLightStatus.value = '连接失败'
    visibleLightLoading.value = false
    visibleLightHasVideo.value = false
  }
}

// 连接深度相机视频流
const connectDepthCameraVideo = async () => {
  if (!depthCameraVideo.value) return
  
  try {
    depthCameraLoading.value = true
    depthCameraStatus.value = '连接中...'
    
    const video = depthCameraVideo.value
    const pc = new RTCPeerConnection({
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' }
      ]
    })
    
    pc.addTransceiver('video', { direction: 'recvonly' })
    pc.addTransceiver('audio', { direction: 'recvonly' })
    
    depthCameraConnection.value = pc
    
    pc.ontrack = async (event) => {
      console.log('✅ 深度相机视频流已接收')
      video.srcObject = event.streams[0]
      await safePlayVideo(video, { muted: true })
      depthCameraHasVideo.value = true
      depthCameraStatus.value = '已连接'
      depthCameraLoading.value = false
    }
    
    pc.oniceconnectionstatechange = () => {
      if (pc.iceConnectionState === 'connected') {
        depthCameraStatus.value = '已连接'
        depthCameraLoading.value = false
      } else if (pc.iceConnectionState === 'failed') {
        depthCameraStatus.value = '连接失败'
        depthCameraLoading.value = false
      }
    }
    
    const offer = await pc.createOffer()
    await pc.setLocalDescription(offer)
    
    // 深度相机可以使用相同的流或不同的流，这里暂时使用相同流
    const response = await fetch(buildUrls.srsApi('/rtc/v1/play/'), {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        api: buildUrls.srsApi('/rtc/v1/play/'),
        streamurl: buildUrls.webrtc(),
        sdp: offer.sdp
      })
    })
    
    if (response.ok) {
      const data = await response.json()
      if (data.code === 0) {
        await pc.setRemoteDescription(new RTCSessionDescription({
          type: 'answer',
          sdp: data.sdp
        }))
      } else {
        throw new Error(data.message || '连接失败')
      }
    } else {
      throw new Error('HTTP错误: ' + response.status)
    }
  } catch (error) {
    console.error('深度相机视频连接失败:', error)
    depthCameraStatus.value = '连接失败'
    depthCameraLoading.value = false
    depthCameraHasVideo.value = false
  }
}

// 可见光视频事件处理
const handleVisibleLightCanPlay = () => {
  visibleLightHasVideo.value = true
  visibleLightStatus.value = '已连接'
  visibleLightLoading.value = false
}

const handleVisibleLightError = () => {
  visibleLightStatus.value = '连接失败'
  visibleLightLoading.value = false
  visibleLightHasVideo.value = false
}

// 深度相机视频事件处理
const handleDepthCameraCanPlay = () => {
  depthCameraHasVideo.value = true
  depthCameraStatus.value = '已连接'
  depthCameraLoading.value = false
}

const handleDepthCameraError = () => {
  depthCameraStatus.value = '连接失败'
  depthCameraLoading.value = false
  depthCameraHasVideo.value = false
}

// 清理视频连接
const cleanupVideoConnections = () => {
  if (visibleLightConnection.value) {
    visibleLightConnection.value.close()
    visibleLightConnection.value = null
  }
  if (depthCameraConnection.value) {
    depthCameraConnection.value.close()
    depthCameraConnection.value = null
  }
  if (visibleLightVideo.value) {
    visibleLightVideo.value.srcObject = null
  }
  if (depthCameraVideo.value) {
    depthCameraVideo.value.srcObject = null
  }
}

// 小车控制方法
const handleCarControl = async (action) => {
  try {
    if (!carControlConnected.value) {
      console.warn('⚠️ 控制服务未连接，尝试连接...')
      await carControlClient.connect()
      carControlConnected.value = true
    }
    
    await carControlClient.controlCar(action)
    console.log(`✅ 小车控制: ${action}`)
  } catch (error) {
    console.error(`❌ 小车控制失败 (${action}):`, error)
    carControlConnected.value = false
  }
}

// 速度控制
const handleSpeedControl = async (action) => {
  try {
    if (action === 'increase') {
      carSpeed.value = Math.min(100, carSpeed.value + 10)
    } else if (action === 'decrease') {
      carSpeed.value = Math.max(0, carSpeed.value - 10)
    }
    
    // 设置四个轮子的速度
    await carControlClient.setSpeed(
      carSpeed.value,
      carSpeed.value,
      carSpeed.value,
      carSpeed.value
    )
    console.log(`✅ 速度已设置为: ${carSpeed.value}%`)
  } catch (error) {
    console.error('❌ 速度控制失败:', error)
  }
}

// 云台控制方法
const handleGimbalControl = async (direction) => {
  try {
    if (!carControlConnected.value) {
      await carControlClient.connect()
      carControlConnected.value = true
    }
    
    let servoIndex, pwm
    
    switch (direction) {
      case 'up':
        servoIndex = gimbalServoIndex.vertical
        pwm = 1800 // 向上（从1500中心向上移动300）
        break
      case 'down':
        servoIndex = gimbalServoIndex.vertical
        pwm = 1200 // 向下（从1500中心向下移动300）
        break
      case 'left':
        servoIndex = gimbalServoIndex.horizontal
        pwm = 1000 // 向左
        break
      case 'right':
        servoIndex = gimbalServoIndex.horizontal
        pwm = 2000 // 向右
        break
      case 'center':
        // 回到中心位置（增大移动时间，使移动幅度更大）
        await carControlClient.controlServo(gimbalServoIndex.horizontal, 1500, 1500)
        await carControlClient.controlServo(gimbalServoIndex.vertical, 1500, 1500)
        return
      default:
        return
    }
    
    await carControlClient.controlServo(servoIndex, pwm, 1000)
    console.log(`✅ 云台控制: ${direction}`)
  } catch (error) {
    console.error(`❌ 云台控制失败 (${direction}):`, error)
  }
}


// 生命周期
onMounted(() => {
  updateTime()
  setInterval(updateTime, 1000) // 每秒更新时间
  loadStatistics()
  loadMaps()
  loadSessions()
  
  // 延迟连接视频流，确保DOM已渲染
  setTimeout(() => {
    connectVisibleLightVideo()
    connectDepthCameraVideo()
  }, 1000)
  
  // 连接小车控制服务
  carControlClient.connect().then(() => {
    carControlConnected.value = true
    console.log('✅ 小车控制服务已连接')
  }).catch(error => {
    console.error('❌ 小车控制服务连接失败:', error)
    carControlConnected.value = false
  })
  
  // 监听控制服务状态
  carControlClient.on('connected', () => {
    carControlConnected.value = true
    console.log('✅ 小车控制服务已连接')
  })
  
  carControlClient.on('disconnected', () => {
    carControlConnected.value = false
    console.warn('⚠️ 小车控制服务已断开')
  })
  
  carControlClient.on('error', (error) => {
    console.error('❌ 小车控制服务错误:', error)
    carControlConnected.value = false
  })
})

onUnmounted(() => {
  cleanupVideoConnections()
  // 断开小车控制连接
  if (carControlClient) {
    carControlClient.disconnect()
  }
})
</script>

<style scoped>
/* 自定义样式 */
</style>
